package com.xbongbong.pro.statistics.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.wrap.BaseDTO;
import com.xbongbong.paas.toolbox.wrap.BaseVO;
import com.xbongbong.paas.toolbox.wrap.XbbResponse;
import com.xbongbong.pro.constant.XbbProConstant;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.statistic.pojo.ChartSavePojo;
import com.xbongbong.pro.statistic.pojo.ChartSystemSavePojo;
import com.xbongbong.pro.statistic.pojo.ChartSystemValuePojo;
import com.xbongbong.pro.statistic.pojo.dto.AttrConditionDTO;
import com.xbongbong.pro.statistic.pojo.dto.ChartBaseDTO;
import com.xbongbong.pro.statistic.pojo.dto.ChartDeleteDTO;
import com.xbongbong.pro.statistic.pojo.dto.ChartDrillListDTO;
import com.xbongbong.pro.statistic.pojo.dto.ChartEditDTO;
import com.xbongbong.pro.statistic.pojo.dto.ChartInitDTO;
import com.xbongbong.pro.statistic.pojo.dto.ChartListDTO;
import com.xbongbong.pro.statistic.pojo.dto.ChartListEditDTO;
import com.xbongbong.pro.statistic.pojo.dto.ChartMirrorInstallDTO;
import com.xbongbong.pro.statistic.pojo.dto.ChartMobileFavoriteSaveDTO;
import com.xbongbong.pro.statistic.pojo.dto.ChartMobileListDTO;
import com.xbongbong.pro.statistic.pojo.dto.ChartOperateEnableDTO;
import com.xbongbong.pro.statistic.pojo.dto.ChartPublishDTO;
import com.xbongbong.pro.statistic.pojo.dto.ChartSavePositionDTO;
import com.xbongbong.pro.statistic.pojo.dto.ChartSaveStyleDTO;
import com.xbongbong.pro.statistic.pojo.dto.ChartSubFormListDTO;
import com.xbongbong.pro.statistic.pojo.dto.ChartThroughDTO;
import com.xbongbong.pro.statistic.pojo.dto.ChartValueSaveDTO;
import com.xbongbong.pro.statistic.pojo.dto.CustomChartDeleteDTO;
import com.xbongbong.pro.statistic.pojo.dto.DataSourceAttrDTO;
import com.xbongbong.pro.statistic.pojo.dto.FirstCategoryDTO;
import com.xbongbong.pro.statistic.pojo.dto.FormIdBusinessTypeAttrDTO;
import com.xbongbong.pro.statistic.pojo.dto.LinkageListDTO;
import com.xbongbong.pro.statistic.pojo.dto.LinkageSaveDTO;
import com.xbongbong.pro.statistic.pojo.dto.NumFormatGetDTO;
import com.xbongbong.pro.statistic.pojo.dto.NumFormatSaveDTO;
import com.xbongbong.pro.statistic.pojo.dto.SearchAttrDTO;
import com.xbongbong.pro.statistic.pojo.dto.ShowTypeDTO;
import com.xbongbong.pro.statistic.pojo.dto.SocketResultDTO;
import com.xbongbong.pro.statistic.pojo.vo.AttrConditionVO;
import com.xbongbong.pro.statistic.pojo.vo.ChartBaseVO;
import com.xbongbong.pro.statistic.pojo.vo.ChartBatchSaveVo;
import com.xbongbong.pro.statistic.pojo.vo.ChartDataLimitVO;
import com.xbongbong.pro.statistic.pojo.vo.ChartDeleteVO;
import com.xbongbong.pro.statistic.pojo.vo.ChartDrillListVO;
import com.xbongbong.pro.statistic.pojo.vo.ChartEditVO;
import com.xbongbong.pro.statistic.pojo.vo.ChartInitVO;
import com.xbongbong.pro.statistic.pojo.vo.ChartMirrorInstallVO;
import com.xbongbong.pro.statistic.pojo.vo.ChartMobileFavoriteSaveVO;
import com.xbongbong.pro.statistic.pojo.vo.ChartMobileListVO;
import com.xbongbong.pro.statistic.pojo.vo.ChartPermissionAndRuleDTO;
import com.xbongbong.pro.statistic.pojo.vo.ChartPermissionAndRuleVO;
import com.xbongbong.pro.statistic.pojo.vo.ChartPublishVO;
import com.xbongbong.pro.statistic.pojo.vo.ChartSaveVO;
import com.xbongbong.pro.statistic.pojo.vo.ChartSubFormListVO;
import com.xbongbong.pro.statistic.pojo.vo.ChartThroughVO;
import com.xbongbong.pro.statistic.pojo.vo.ChartTypeListVO;
import com.xbongbong.pro.statistic.pojo.vo.CustomChartDeleteVO;
import com.xbongbong.pro.statistic.pojo.vo.DataSourceAttrVO;
import com.xbongbong.pro.statistic.pojo.vo.FirstCategoryVO;
import com.xbongbong.pro.statistic.pojo.vo.LinkageListVO;
import com.xbongbong.pro.statistic.pojo.vo.NumFormatGetVO;
import com.xbongbong.pro.statistic.pojo.vo.NumFormatSaveVO;
import com.xbongbong.pro.statistic.pojo.vo.NumberAttrVO;
import com.xbongbong.pro.statistic.pojo.vo.ShowTypeVO;
import com.xbongbong.pro.statistic.pojo.vo.SocketReckonVO;
import com.xbongbong.pro.statistic.result.pojo.dto.ChartPenetrateResultDTO;
import com.xbongbong.pro.statistic.result.pojo.dto.ChartResultAggDTO;
import com.xbongbong.pro.statistic.result.pojo.dto.ChartResultBaseDTO;
import com.xbongbong.pro.statistic.result.pojo.dto.ChartResultCallStatisticsDTO;
import com.xbongbong.pro.statistic.result.pojo.dto.ChartResultDTO;
import com.xbongbong.pro.statistic.result.pojo.dto.ChartResultPerformancePkDTO;
import com.xbongbong.pro.statistic.result.pojo.vo.CallStatisticsVO;
import com.xbongbong.pro.statistic.result.pojo.vo.ChartResultAggVO;
import com.xbongbong.pro.statistic.result.pojo.vo.ChartResultPkDetailVO;
import com.xbongbong.pro.statistic.result.pojo.vo.ChartResultPkVO;
import com.xbongbong.pro.statistic.result.pojo.vo.ChartResultVO;
import com.xbongbong.pro.statistic.result.pojo.vo.ChartResultValueVO;
import com.xbongbong.pro.statistic.result.pojo.vo.FundFlowVO;
import com.xbongbong.pro.statistic.result.pojo.vo.PerformanceFinishVO;
import com.xbongbong.pro.statistic.service.ChartResultService;
import com.xbongbong.pro.statistic.service.ChartService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Objects;

/**
 * 创建时间： 2019/1/14 13:42
 * 修改时间： 2019/1/14 13:42 梁鲁江
 *
 * @author 梁鲁江
 */
@RestController
@RequestMapping(value = XbbProConstant.API_ROOT_PREFIX + "/chart")
public class ChartController {
    @Resource
    private ChartService  chartService;
    @Resource
    private ChartResultService chartResultService;
    @Resource
    private PaasRedisHelper paasRedisHelper;
    @Resource
    private CommonHelp commonHelp;

    private static final Logger LOG = LoggerFactory.getLogger(ChartController.class);
    /**
     * 2.2.12 获取指标/图表基本信息列表
     * @param chartBaseDTO  入参
     * @param br  校验信息
     * @return  ChartBaseVO
     */
    @RequestMapping(value = "/baseList", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String baseList(@RequestBody @Valid ChartBaseDTO chartBaseDTO, BindingResult br) {
        XbbResponse<ChartBaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            //请求参数后处理，比如trim
            chartBaseDTO.postProcess();
            try {
                ChartBaseVO chartBaseVO = chartService.chartBaseList(chartBaseDTO);
                response = new XbbResponse<>(chartBaseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 2.2.1 图表列表
     * @param chartBaseDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/list", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String chartList(@RequestBody @Valid ChartListDTO chartBaseDTO, BindingResult br) {
        XbbResponse<ChartSavePojo> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            //请求参数后处理，比如trim
            chartBaseDTO.postProcess();
            try {
                ChartSavePojo chartBaseVO = chartService.chartList(chartBaseDTO);
                response = new XbbResponse<>(chartBaseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 通过分类id获取图表，当没有分类id时，必须要输入要筛选的图表名称
     * @param chartBaseDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/byCategory/list", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String chartListByCategory(@RequestBody @Valid ChartListDTO chartBaseDTO, BindingResult br) {
        XbbResponse<ChartSavePojo> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            //请求参数后处理，比如trim
            chartBaseDTO.postProcess();
            try {
                ChartSavePojo chartBaseVO = chartService.chartListByCategory(chartBaseDTO);
                response = new XbbResponse<>(chartBaseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     *  数据来源(2) 选定数据源之后提供待选字段
     * @param dataSourceAttrDTO  校验信息
     * @param br 校验信息
     * @return  DataSourceAttrVO
     */
    @RequestMapping(value = "/dataSourceAttr", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String dataSourceAttr(@RequestBody @Valid DataSourceAttrDTO dataSourceAttrDTO, BindingResult br) {
        XbbResponse<DataSourceAttrVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DataSourceAttrVO dataSourceAttrVO = chartService.dataSourceAttr(dataSourceAttrDTO);
                response = new XbbResponse<>(dataSourceAttrVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
       return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    
    @RequestMapping(value = "/chartDataLimit", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String chartDataLimit(@RequestBody @Valid DataSourceAttrDTO dataSourceAttrDTO, BindingResult br) {
        XbbResponse<ChartDataLimitVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ChartDataLimitVO chartDataLimitVO = chartService.chartDataLimit(dataSourceAttrDTO);
                response = new XbbResponse<>(chartDataLimitVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
       return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 全局查询条件的可选字段
     * @param searchAttrDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/searchSourceAttr", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String searchSourceAttr(@RequestBody @Valid SearchAttrDTO searchAttrDTO, BindingResult br) {
        XbbResponse<DataSourceAttrVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DataSourceAttrVO dataSourceAttrVO = chartService.searchSourceAttr(searchAttrDTO);
                response = new XbbResponse<>(dataSourceAttrVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
       return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     *  根据formId集合查询所有的数字字段
     * @param formIdBusinessTypeAttrDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/searchNumberAttr", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String searchSourceAttr(@RequestBody @Valid FormIdBusinessTypeAttrDTO formIdBusinessTypeAttrDTO, BindingResult br) {
        XbbResponse<NumberAttrVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                NumberAttrVO numberAttrVO = chartService.searchNumberAttr(formIdBusinessTypeAttrDTO);
                response = new XbbResponse<>(numberAttrVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 图表的保存
     * @param chartSavePojo
     * @param br
     * @return
     */
    @RequestMapping(value = "/save", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String chartSave(@RequestBody @Valid ChartSavePojo chartSavePojo, BindingResult br) {
        XbbResponse<ChartBatchSaveVo> response;
        //对中文字段name长度为20，英文长度name_en为50的特殊校验
        if (br.hasErrors()){
            try {
                commonHelp.checkNameLength(br.getFieldError());
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
                return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
            }
        }
        try {
            // ----------------------------------repeat post----------------------------------------------
            // 判断是否跳过重复提交校验
            if (!Boolean.TRUE.equals(chartSavePojo.getIgnoreConCheck())) {
                //重复提交校验
                if (!paasRedisHelper.checkConcurrentLock(chartSavePojo)) {
                    response = new XbbResponse<>(new XbbException(SystemErrorCodeEnum.API_ERROR_100003));
                    return JSON.toJSONString(response);
                }
            }
            // ----------------------------------repeat post----------------------------------------------
            ChartBatchSaveVo chartBatchSaveVo = null;
            try {
                chartBatchSaveVo = chartService.chartSave(chartSavePojo);
            } catch (IllegalAccessException | InstantiationException e) {
                LOG.error("",e);
                throw  new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }
            response = new XbbResponse<>(chartBatchSaveVo);
        } catch (XbbException e) {
            response = new XbbResponse<>(e);
        }
       return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 自定义指标的保存
     * @param chartValueSaveDTO  入参
     * @param br  异常捕获
     * @return
     */
    @RequestMapping(value = "/value/save", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String chartValueSave(@RequestBody @Validated(value = {ChartService.class}) ChartValueSaveDTO chartValueSaveDTO, BindingResult br) {
        XbbResponse<ChartSaveVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                // ----------------------------------repeat post----------------------------------------------
                // 判断是否跳过重复提交校验
                if (!Boolean.TRUE.equals(chartValueSaveDTO.getIgnoreConCheck())) {
                    //重复提交校验
                    if (!paasRedisHelper.checkConcurrentLock(chartValueSaveDTO)) {
                        response = new XbbResponse<>(new XbbException(SystemErrorCodeEnum.API_ERROR_100003));
                        return JSON.toJSONString(response);
                    }
                }
                // ----------------------------------repeat post----------------------------------------------
                ChartSaveVO chartSaveVO = chartService.chartValueSave(chartValueSaveDTO);
                response = new XbbResponse<>(chartSaveVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
       return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/system/update", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String chartSystemValueUpdate(@RequestBody @Valid ChartSystemValuePojo chartSystemValuePojo, BindingResult br) {
        XbbResponse<ChartSaveVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ChartSaveVO chartSaveVO = chartService.chartSystemValueSave(chartSystemValuePojo);
                response = new XbbResponse<>(chartSaveVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
       return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 编辑图表
     * @param chartEditDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/edit", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String chartEdit(@RequestBody @Valid ChartEditDTO chartEditDTO, BindingResult br) {
        XbbResponse<ChartEditVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ChartEditVO chartEditVO = chartService.chartEdit(chartEditDTO);
                response = new XbbResponse<>(chartEditVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
       return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/listEdit", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String chartListEdit(@RequestBody @Valid ChartListEditDTO chartListEditDTO, BindingResult br) {
        XbbResponse<ChartSavePojo> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ChartSavePojo chartSavePojo = chartService.chartListEdit(chartListEditDTO);
                response = new XbbResponse<>(chartSavePojo);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
       return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/getAttrCondition", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getAttrCondition(@RequestBody @Valid AttrConditionDTO attrConditionDTO, BindingResult br) {
        XbbResponse<AttrConditionVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                AttrConditionVO attrCondition = chartService.getAttrCondition(attrConditionDTO);
                response = new XbbResponse<>(attrCondition);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
       return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 指标删除(图表在save里)
     * @param chartDeleteDTO 入参
     * @param br 校验信息
     * @return java.lang.String
     * @throws XbbException
     * @author zcp
     * @date 2019/1/24 9:32
     * @since v1.0
     * @version v1.0
     */
    @RequestMapping(value = "/delete", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String chartDelete(@RequestBody @Valid ChartDeleteDTO chartDeleteDTO, BindingResult br) {
        XbbResponse<ChartDeleteVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ChartDeleteVO chartDeleteVO = chartService.chartDelete(chartDeleteDTO);
                response = new XbbResponse<>(chartDeleteVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
       return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }
    @RequestMapping(value = "/getShowType", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getShowType(@RequestBody @Valid ShowTypeDTO showTypeDTO, BindingResult br) {
        XbbResponse<ShowTypeVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ShowTypeVO showType = chartService.getShowType(showTypeDTO);
                response = new XbbResponse<>(showType);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
       return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 新建、取消收藏
     * @param chartMobileFavoriteSaveDTO 入参
     * @param br 校验信息
     * @return java.lang.String response
     * @author zcp
     * @date 2019/1/29 14:45
     * @since v1.0
     * @version v1.0
     */
    @RequestMapping(value = "/mobile/favorite/save", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String chartMobileFavoriteSave(@RequestBody @Valid ChartMobileFavoriteSaveDTO chartMobileFavoriteSaveDTO, BindingResult br) {
        XbbResponse<ChartMobileFavoriteSaveVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ChartMobileFavoriteSaveVO chartMobileFavoriteSaveVO = chartService.chartMobileFavoriteSave(chartMobileFavoriteSaveDTO);
                response = new XbbResponse<>(chartMobileFavoriteSaveVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 移动端图表列表
     * @param chartMobileListDTO 入参
     * @param br 校验信息
     * @return java.lang.String response
     * @throws
     * @author zcp
     * @date 2019/1/29 16:11
     * @since v1.0
     * @version v1.0
     */
    @RequestMapping(value = "/mobile/list", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String chartMobileList(@RequestBody @Valid ChartMobileListDTO chartMobileListDTO, BindingResult br) {
        XbbResponse<ChartMobileListVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            //请求参数后处理，比如trim
            chartMobileListDTO.postProcess();
            try {
                ChartMobileListVO chartMobileListVO = chartService.chartMobileList(chartMobileListDTO);
                response = new XbbResponse<>(chartMobileListVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 图表初始化
     *
     * @param chartInitDTO 入参（包含corpid）
     * @param br           校验信息
     * @return java.lang.String
     * @author 徐俊杰
     * @date 2019/1/31 16:22
     * @since v1.0
     */
    @RequestMapping(value = "/init", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String chartInit(@RequestBody @Valid ChartInitDTO chartInitDTO, BindingResult br) {
        XbbResponse<ChartInitVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ChartInitVO chartInitVO = chartService.chartInit(chartInitDTO);
                response = new XbbResponse<>(chartInitVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 获取图表统计结果
     * @param chartResultDTO 入参
     * @param br 校验信息
     * @return java.lang.String response
     * @author zcp
     * @date 2019/2/14 14:42
     * @since v1.0
     * @version v1.0
     */
    @RequestMapping(value = "/result", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String chartResult(@RequestBody @Valid ChartResultDTO chartResultDTO, BindingResult br) {
        XbbResponse<ChartResultVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                //请求参数后处理，比如del、enable
                chartResultDTO.postProcess();
                ChartResultVO chartResultVO = chartResultService.chartResult(chartResultDTO);
                response = new XbbResponse<>(chartResultVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 图表穿透
     * @param chartPenetrateResultDTO 入参
     * @param br 校验信息
     * @return java.lang.String response
     * @author zhouwq
     * @date 2019/4/18 11:19
     */
    @RequestMapping(value = "/result/penetrate", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String chartPenetrateResult(@RequestBody @Valid ChartPenetrateResultDTO chartPenetrateResultDTO, BindingResult br) {
        XbbResponse<ChartResultVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                //请求参数后处理，比如del、enable
                chartPenetrateResultDTO.postProcess();
                ChartResultVO chartResultVO = chartResultService.chartPenetrateResult(chartPenetrateResultDTO);
                response = new XbbResponse<>(chartResultVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 获取首页看板结果
     *
     * @param chartResultDTO 入参
     * @param br             校验信息
     * @return java.lang.String
     * @author 徐俊杰
     * @date 2019/3/12 17:23
     * @since v1.0
     */
    @RequestMapping(value = "/result/value", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String chartResultValue(@RequestBody @Valid ChartResultDTO chartResultDTO, BindingResult br) {
        XbbResponse<ChartResultValueVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                //请求参数后处理，比如del、enable
                chartResultDTO.postProcess();
                ChartResultValueVO chartResultValueVO = chartResultService.chartResultValue(chartResultDTO);
                response = new XbbResponse<>(chartResultValueVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * websocket统计专用请求接口
     * @param socketResultDTO 入参
     * @param br 校验信息
     * @return java.lang.String response
     * @author zcp
     * @date 2019/2/14 14:42
     * @since v1.0
     * @version v1.0
     */
    @RequestMapping(value = "/socketReckon", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String socketReckon(@RequestBody @Valid SocketResultDTO socketResultDTO, BindingResult br) {
        XbbResponse<SocketReckonVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                SocketReckonVO socketReckonVO = chartResultService.socketReckon(socketResultDTO);
                response = new XbbResponse<>(socketReckonVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }
    /**
     * 获取pk结果
     * @param chartResultDTO 入参
     * @param br             校验信息
     * @return java.lang.String
     * @throws XbbException
     * @author zcp
     * @date 2019/3/18 20:11
     * @since v1.0
     * @version v1.0
     */
    @RequestMapping(value = "/result/pk", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String chartResultPk(@RequestBody @Valid ChartResultDTO chartResultDTO, BindingResult br) {
        XbbResponse<ChartResultPkVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                //请求参数后处理，比如del、enable
                chartResultDTO.postProcess();
                ChartResultPkVO chartResultPkVO = chartResultService.chartResultPk(chartResultDTO);
                response = new XbbResponse<>(chartResultPkVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 获取pk榜范围设置pk结果
     * @param chartResultDTO 入参
     * @param br             校验信息
     * @return java.lang.String
     * @throws XbbException
     * @author youli.chen
     * @date 2020/9/9 20:11
     * @since v1.0
     * @version v1.0
     */
    @RequestMapping(value = "/result/rule/pk", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String chartResultRulePk(@RequestBody @Valid ChartResultDTO chartResultDTO, BindingResult br) {
        XbbResponse<ChartResultPkVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                //请求参数后处理，比如del、enable
                chartResultDTO.postProcess();
                ChartResultPkVO chartResultPkVO = chartResultService.chartResultRulePk(chartResultDTO);
                response = new XbbResponse<>(chartResultPkVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 获取业绩目标 结果
     * 首页业绩目标、web完成情况详情页、app端列表页
     * @param chartResultDTO 入参
     * @param br             校验信息
     * @return java.lang.String
     * @throws
     * @author zcp
     * @date 2019/3/29 16:36
     * @since v1.0
     * @version v1.0
     */
    @RequestMapping(value = "/result/performance", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String chartResultPerformance(@RequestBody @Valid ChartResultDTO chartResultDTO, BindingResult br) {
        XbbResponse<ChartResultPkDetailVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                //请求参数后处理，比如del、enable
                chartResultDTO.postProcess();
                ChartResultPkDetailVO chartResultPkDetailVO = chartResultService.chartResultPerformance(chartResultDTO);
                response = new XbbResponse<>(chartResultPkDetailVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 员工目标完成情况：目标完成情况详情穿透（人员完成率排行），所有员工的所有指标（在考核对象内）的完成情况
     * @param chartResultPerformancePkDTO 入参
     * @param br                          校验信息
     * @return java.lang.String
     * @throws XbbException
     * @author zcp
     * @date 2019/4/4 15:17
     * @since v1.0
     * @version v1.0
     */
    @RequestMapping(value = "/result/performance/pk", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String chartResultPerformancePk(@RequestBody @Valid ChartResultPerformancePkDTO chartResultPerformancePkDTO, BindingResult br) {
        XbbResponse<ChartResultPkDetailVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ChartResultPkDetailVO chartResultPkDetailVO = chartResultService.chartResultPerformancePk(chartResultPerformancePkDTO);
                response = new XbbResponse<>(chartResultPkDetailVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 目标完成情况
     *
     * @param chartResultBaseDTO 入参
     * @param br                 校验信息
     * @return java.lang.String
     * @throws XbbException
     * @author zcp
     * @date 2019/4/2 14:53
     * @since v1.0
     * @version v1.0
     */
    @RequestMapping(value = "/result/performance/finish", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String chartResultPerformanceFinish(@RequestBody @Valid ChartResultBaseDTO chartResultBaseDTO, BindingResult br) {
        XbbResponse<PerformanceFinishVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                PerformanceFinishVO performanceFinishVO = chartResultService.chartResultPerformanceFinish(chartResultBaseDTO);
                response = new XbbResponse<>(performanceFinishVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 员工呼出/呼入统计
     *
     * @param chartResultCallStatisticsDTO 入参
     * @param br                 校验信息
     * @return java.lang.String
     * @throws XbbException
     * @author youli.chen
     * @date 2019/4/2 14:53
     * @since v1.0
     * @version v1.0
     */
    @RequestMapping(value = "/result/call/statistics", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String chartResultCallStatistics(@RequestBody @Valid ChartResultCallStatisticsDTO chartResultCallStatisticsDTO, BindingResult br) {
        XbbResponse<CallStatisticsVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                CallStatisticsVO callStatisticsVO = chartResultService.chartResultCallStatistics(chartResultCallStatisticsDTO);
                response = new XbbResponse<>(callStatisticsVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 员工呼出/呼入统计数据总计
     *
     * @param chartResultCallStatisticsDTO 入参
     * @param br                 校验信息
     * @return java.lang.String
     * @throws XbbException
     * @author youli.chen
     * @date 2019/4/2 14:53
     * @since v1.0
     * @version v1.0
     */
    @RequestMapping(value = "/result/call/statistics/total", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String chartResultCallStatisticsTotal(@RequestBody @Valid ChartResultCallStatisticsDTO chartResultCallStatisticsDTO, BindingResult br) {
        XbbResponse<CallStatisticsVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                CallStatisticsVO callStatisticsVO = chartResultService.chartResultCallStatisticsTotal(chartResultCallStatisticsDTO);
                response = new XbbResponse<>(callStatisticsVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/result/agg", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String chartResultAgg(@RequestBody @Valid ChartResultAggDTO chartResultAggDTO, BindingResult br){
        XbbResponse<ChartResultAggVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                //请求参数后处理，比如del、enable
                chartResultAggDTO.postProcess();
                ChartResultAggVO chartResultAggVO = chartResultService.chartRenderResultAgg(chartResultAggDTO);
                response = new XbbResponse<>(chartResultAggVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 图表权限添加/修改
     * @param chartSystemSavePojo 入参
     * @param br 校验信息
     * @author zhouwq
     * @date 2019/4/30 15:40
     * @return java.lang.String
     */
    @RequestMapping(value = "/system/rule/update", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String chartPermissionsUpdate(@RequestBody @Valid ChartSystemSavePojo chartSystemSavePojo, BindingResult br){
        XbbResponse<ChartBatchSaveVo> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                // ----------------------------------repeat post----------------------------------------------
                // 判断是否跳过重复提交校验
                if (!Boolean.TRUE.equals(chartSystemSavePojo.getIgnoreConCheck())) {
                    //重复提交校验
                    if (!paasRedisHelper.checkConcurrentLock(chartSystemSavePojo)) {
                        response = new XbbResponse<>(new XbbException(SystemErrorCodeEnum.API_ERROR_100003));
                        return JSON.toJSONString(response);
                    }
                }
                // ----------------------------------repeat post----------------------------------------------
                ChartBatchSaveVo chartBatchSaveVo = null;
                chartBatchSaveVo = chartService.chartPermissionsUpdate(chartSystemSavePojo);
                response = new XbbResponse<>(chartBatchSaveVo);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }
    @RequestMapping(value = "/salesFunnel/rule/update", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String salesFunnelPermissionsUpdate(@RequestBody @Valid ChartSystemSavePojo chartSystemSavePojo, BindingResult br){
        XbbResponse<ChartBatchSaveVo> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                // ----------------------------------repeat post----------------------------------------------
                // 判断是否跳过重复提交校验
                if (!Boolean.TRUE.equals(chartSystemSavePojo.getIgnoreConCheck())) {
                    //重复提交校验
                    if (!paasRedisHelper.checkConcurrentLock(chartSystemSavePojo)) {
                        response = new XbbResponse<>(new XbbException(SystemErrorCodeEnum.API_ERROR_100003));
                        return JSON.toJSONString(response);
                    }
                }
                // ----------------------------------repeat post----------------------------------------------
                ChartBatchSaveVo chartBatchSaveVo = null;
                chartBatchSaveVo = chartService.salesFunnelPermissionsUpdate(chartSystemSavePojo);
                response = new XbbResponse<>(chartBatchSaveVo);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 图表权限获取
     * @param chartEditDTO 入参
     * @param br 校验信息
     * @author zhouwq
     * @date 2019/4/30 15:40
     * @return java.lang.String
     */
    @RequestMapping(value = "/system/rule/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String chartPermissionsEdit(@RequestBody @Valid ChartEditDTO chartEditDTO, BindingResult br) {
        XbbResponse<ChartEditVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ChartEditVO chartEditVO = chartService.chartPermissionsGet(chartEditDTO);
                response = new XbbResponse<>(chartEditVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 销售漏斗图表的操作权限和统计规则获取. 销售漏斗的图表设置，比较特殊，冗余一个接口
     * @param chartEditDTO 入参
     * @param br 校验信息
     * @author qinchunyang
     * @date 2020/8/24 15:40
     * @return java.lang.String
     */
    @RequestMapping(value = "/salesFunnel/rule/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String chartPermissionsAndStatisticsRule(@RequestBody @Valid ChartPermissionAndRuleDTO chartEditDTO, BindingResult br) {
        XbbResponse<ChartEditVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ChartPermissionAndRuleVO chartEditVO = chartService.chartPermissionAndRuleGet(chartEditDTO);
                response = new XbbResponse<>(chartEditVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }


    /**
     * 图表发布到首页
     *
     * @param chartPublishDTO 入参
     * @param br 校验信息
     * @return java.lang.String
     * @author 徐俊杰
     * @date 2019/5/5 9:12
     * @since v1.0
     */
    @RequestMapping(value = "/publish", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String publish(@RequestBody @Valid ChartPublishDTO chartPublishDTO, BindingResult br) {
        XbbResponse<ChartPublishVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ChartPublishVO chartPublishVO = chartService.chartPublish(chartPublishDTO);
                response = new XbbResponse<>(chartPublishVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }
    /**
     * 二级分类获取一级分类
     *
     * @param firstCategoryDTO 入参
     * @param br 校验信息
     * @return java.lang.String
     * @author 徐俊杰
     * @date 2019/5/16 15:45
     * @since v1.0
     */
    @RequestMapping(value = "/publish/firstCategory", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String firstCategory(@RequestBody @Valid FirstCategoryDTO firstCategoryDTO, BindingResult br) {
        XbbResponse<FirstCategoryVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                FirstCategoryVO firstCategoryVO = chartService.firstCategory(firstCategoryDTO);
                response = new XbbResponse<>(firstCategoryVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/mirrorInstallChart", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String mirrorInstallChart(@RequestBody @Valid ChartMirrorInstallDTO baseDTO, BindingResult br) {
        XbbResponse<ChartMirrorInstallVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ChartMirrorInstallVO chartMirrorInstallVO = chartService.mirrorInstall(baseDTO);
                response = new XbbResponse<>(chartMirrorInstallVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }


    @RequestMapping(value = "/fund/flow", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String fundFlow(@RequestBody @Valid ChartResultDTO chartResultDTO, BindingResult br) {
        XbbResponse<FundFlowVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                FundFlowVO fundFlowVO = chartResultService.getFundFlow(chartResultDTO);
                response = new XbbResponse<>(fundFlowVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 仪表盘中图表的位置信息保存以及删除图表
     * @param chartSavePositionDTO 入参
     * @param br 校验信息
     * @return string
     * @author zhouwq
     * @date 2020/9/24 13:37
     */
    @RequestMapping(value = "/update/dashboard", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String chartUpdateDashboard(@RequestBody @Valid ChartSavePositionDTO chartSavePositionDTO, BindingResult br) {
        XbbResponse<ChartSaveVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                // ----------------------------------repeat post----------------------------------------------
                // 判断是否跳过重复提交校验
                if (!Boolean.TRUE.equals(chartSavePositionDTO.getIgnoreConCheck())) {
                    //重复提交校验
                    if (!paasRedisHelper.checkConcurrentLock(chartSavePositionDTO)) {
                        response = new XbbResponse<>(new XbbException(SystemErrorCodeEnum.API_ERROR_100003));
                        return JSON.toJSONString(response);
                    }
                }
                // ----------------------------------repeat post----------------------------------------------
                ChartSaveVO chartSaveVO = chartService.chartUpdateDashboard(chartSavePositionDTO);
                response = new XbbResponse<>(chartSaveVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 仪表盘中图表的样式和全局样式保存
     * @param chartSaveStyleDTO 入参
     * @param br 校验信息
     * @return string
     * @author weiming
     * @date 2021/3/15 13:37
     */
    @RequestMapping(value = "/update/style", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String chartUpdateDisplay(@RequestBody @Valid ChartSaveStyleDTO chartSaveStyleDTO, BindingResult br) {
        XbbResponse<ChartSaveVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                // ----------------------------------repeat post----------------------------------------------
                // 判断是否跳过重复提交校验
                if (!Boolean.TRUE.equals(chartSaveStyleDTO.getIgnoreConCheck())) {
                    //重复提交校验
                    if (!paasRedisHelper.checkConcurrentLock(chartSaveStyleDTO)) {
                        response = new XbbResponse<>(new XbbException(SystemErrorCodeEnum.API_ERROR_100003));
                        return JSON.toJSONString(response);
                    }
                }
                // ----------------------------------repeat post----------------------------------------------
                ChartSaveVO chartSaveVO = chartService.chartUpdateStyle(chartSaveStyleDTO);
                response = new XbbResponse<>(chartSaveVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 删除自定义图表，套餐降版本使用
     * http://yapi.xbongbong.com/project/123/interface/api/17738
     * @param chartDeleteDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/deleteCustom", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String deleteCustomChart(@RequestBody @Valid CustomChartDeleteDTO chartDeleteDTO, BindingResult br) {
        XbbResponse<CustomChartDeleteVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                CustomChartDeleteVO chartDeleteVO = chartService.deleteCustomChart(chartDeleteDTO);
                response = new XbbResponse<>(chartDeleteVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 获取子表单数据
     * @param chartSubFormListDTO 入参
     * @param br 校验信息
     * @return java.lang.String
     * @author zhouwq
     * @date 2020/9/29 9:06
     */
    @RequestMapping(value = "/subFormList", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    public String subFormList(@RequestBody @Valid ChartSubFormListDTO chartSubFormListDTO, BindingResult br) {
        XbbResponse<ChartSubFormListVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ChartSubFormListVO chartSubFormListVO = chartResultService.chartGetSubFormList(chartSubFormListDTO);
                response = new XbbResponse<>(chartSubFormListVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/update/sort", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String chartUpdateSort(@RequestBody @Valid ChartSavePositionDTO chartSavePositionDTO, BindingResult br) {
        XbbResponse<ChartSaveVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                // ----------------------------------repeat post----------------------------------------------
                // 判断是否跳过重复提交校验
                if (!Boolean.TRUE.equals(chartSavePositionDTO.getIgnoreConCheck())) {
                    //重复提交校验
                    if (!paasRedisHelper.checkConcurrentLock(chartSavePositionDTO)) {
                        response = new XbbResponse<>(new XbbException(SystemErrorCodeEnum.API_ERROR_100003));
                        return JSON.toJSONString(response);
                    }
                }
                // ----------------------------------repeat post----------------------------------------------
                ChartSaveVO chartSaveVO = chartService.chartUpdateSort(chartSavePositionDTO);
                response = new XbbResponse<>(chartSaveVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 校验穿透的权限
     * @param throughDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/checkThrough", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String chartListDw(@RequestBody @Valid ChartThroughDTO throughDTO, BindingResult br) {
        XbbResponse<ChartThroughVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ChartThroughVO throughVO = chartService.checkThrough(throughDTO);
                response = new XbbResponse<>(throughVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 校验穿透的权限
     * @param baseDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/chartType/list", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String chartTypeList(@RequestBody @Valid BaseDTO baseDTO, BindingResult br) {
        XbbResponse<ChartTypeListVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ChartTypeListVO chartTypeListVO = chartService.chartTypeList(baseDTO);
                response = new XbbResponse<>(chartTypeListVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 数值格式保存
     * @author xinpeng.jiang
     * @date 2021/10/25 14:15
     * @version 1.0
     * @since V1.0
     */
    @RequestMapping(value = "/save/numFormat", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String saveNumFormat(@RequestBody @Valid NumFormatSaveDTO numFormatSaveDTO, BindingResult br) {
        XbbResponse<NumFormatSaveVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                NumFormatSaveVO numFormatSaveVO = chartService.saveNumFormat(numFormatSaveDTO);
                response = new XbbResponse<>(numFormatSaveVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 数值格式获取
     * @author xinpeng.jiang
     * @date 2021/10/25 14:15
     * @version 1.0
     * @since V1.0
     */
    @RequestMapping(value = "/get/numFormat", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String saveNumFormat(@RequestBody @Valid NumFormatGetDTO numFormatGetDTO, BindingResult br) {
        XbbResponse<NumFormatGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                NumFormatGetVO numFormatGetVO = chartService.getNumFormat(numFormatGetDTO);
                response = new XbbResponse<>(numFormatGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 图表钻取设置-层级列表
     * @param chartDrillListDTO
     * @param br
     * @return java.lang.String
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    @RequestMapping(value = "/drill/list", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String drillList(@RequestBody @Valid ChartDrillListDTO chartDrillListDTO, BindingResult br) {
        XbbResponse<ChartDrillListVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ChartDrillListVO chartDrillListVO = chartService.drillList(chartDrillListDTO);
                response = new XbbResponse<>(chartDrillListVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 图表交互开关：穿透、钻取等开启关闭控制
     * @param chartOperateEnableDTO
     * @param br
     * @return java.lang.String
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    @RequestMapping(value = "/operate/enable", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String operateEnable(@RequestBody @Valid ChartOperateEnableDTO chartOperateEnableDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                BaseVO baseVO = chartService.operateEnable(chartOperateEnableDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 联动设置可选/不可选列表
     *
     * @param linkageListDTO
     * @param br
     * @return java.lang.String
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    @RequestMapping(value = "/linkage/list", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String linkageList(@RequestBody @Valid LinkageListDTO linkageListDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                LinkageListVO linkageListVO = chartService.linkageList(linkageListDTO);
                response = new XbbResponse<>(linkageListVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 联动设置保存/编辑
     *
     * @param linkageSaveDTO
     * @param br
     * @return java.lang.String
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    @RequestMapping(value = "/linkage/save", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String linkageSave(@RequestBody @Valid LinkageSaveDTO linkageSaveDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                BaseVO baseVO = chartService.linkageSave(linkageSaveDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }
}
